package cn.supermarket.service.impl;


import cn.supermarket.ex.ServiceException;
import cn.supermarket.mapper.CategoryMapper;
import cn.supermarket.pojo.dto.CategoryAddNewDTO;

import cn.supermarket.pojo.dto.CategoryUpdateDTO;
import cn.supermarket.pojo.entity.Category;
import cn.supermarket.pojo.entity.FrontCategoryEntity;
import cn.supermarket.pojo.vo.CategoryStandardVO;
import cn.supermarket.pojo.vo.CategoryTreeVO;
import cn.supermarket.service.iservice.ICategoryService;
import cn.supermarket.utils.SnowFlakeGenerateIdWorker;
import cn.supermarket.web.State;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private CategoryMapper mapper;

    @Override
    public Long addCategory(CategoryAddNewDTO categoryAddNewDTO) {
        CategoryStandardVO NameQueryResult = mapper.getByName(categoryAddNewDTO.getName());

        if (NameQueryResult !=null){
            throw new ServiceException(State.ERR_NOT_FOUND,"新增类别失败，类别名称(" + categoryAddNewDTO.getName() + ")已存在！");
        }
        if (categoryAddNewDTO.getParentId()==null){
            categoryAddNewDTO.setParentId(0L);
        }
        CategoryStandardVO categoryStandardVOById = mapper.getById(categoryAddNewDTO.getParentId());
        if (categoryAddNewDTO.getParentId()!=0 && categoryStandardVOById==null){
            throw new ServiceException(State.ERR_NOT_FOUND,"新增类别失败，父级类别不存在！");
        }
        LocalDateTime now = LocalDateTime.now();
        Category category = new Category();
        category.setParentId(categoryAddNewDTO.getParentId());
        category.setName(categoryAddNewDTO.getName());
        category.setKeywords(categoryAddNewDTO.getKeywords());
        category.setHandler(categoryAddNewDTO.getHandler());
        category.setIsEnable(categoryAddNewDTO.getIsEnable());
        category.setIsDisplay(categoryAddNewDTO.getIsDisplay());
        category.setSort(categoryAddNewDTO.getSort() == null ? 0 : categoryAddNewDTO.getSort());
        category.setGmtCreate(now);
        category.setGmtModified(now);
        SnowFlakeGenerateIdWorker snowFlakeGenerateIdWorker = new SnowFlakeGenerateIdWorker(11,12);
        category.setId(snowFlakeGenerateIdWorker.nextId());
        int depth = 1;
        if (categoryAddNewDTO.getParentId() !=0){
            depth = categoryStandardVOById.getDepth()+1;
        }
        category.setDepth(depth);
        category.setIsParent(0);
        int rows = mapper.addCategory(category);
        if (rows!=1){
            throw new ServiceException(State.ERR_INSERT,"新增类别失败,服务器忙,请稍后再次尝试");
        }

        if (categoryAddNewDTO.getParentId()!=0 && categoryStandardVOById.getParentId()==0){
            rows  = mapper.updateParentById(categoryStandardVOById.getId(), 1);
            if (rows!=1){
                throw new ServiceException(State.ERR_INSERT,"新增类别失败,服务器忙,请稍后再次尝试");
            }
        }
        return category.getId();
    }



    @Override
    public void deleteById(Long id) {
        CategoryStandardVO categoryStandardVOById = mapper.getById(id);
        if (categoryStandardVOById == null) {
            throw new ServiceException(State.ERR_NOT_FOUND,"删除类别失败，尝试访问的数据不存在！");
        }
        int count = mapper.countByParentId(id);
        if (count>0){
            throw new ServiceException(State.ERR_BAD_REQUEST,"需要删除的类别中包含子类");
        }
        int rows = mapper.deleteById(id);
        if (rows!=1){
            throw new ServiceException(State.ERR_BAD_REQUEST,"删除失败,服务器忙,请稍后再次尝试");
        }

        if (categoryStandardVOById.getParentId()!=0){
            CategoryStandardVO categoryStandardVO = mapper.getById(categoryStandardVOById.getParentId());
            if (categoryStandardVO!=null){
                List<CategoryStandardVO> categoryStandardVOS = mapper.listByParentId(categoryStandardVO.getId());
                if (categoryStandardVOS.size() == 0){
                    rows = mapper.updateParentById(categoryStandardVO.getId(), 0);
                    if (rows!=1){
                        throw new ServiceException(State.ERR_BAD_REQUEST,"删除失败,服务器忙,请稍后再次尝试");
                    }
                }
            }
        }
    }




    @Override
    public void updateCategoryById(Long id, CategoryUpdateDTO categoryUpdateDTO) {
        CategoryStandardVO categoryStandardVOById = mapper.getById(id);
        if (categoryStandardVOById==null){
            throw new ServiceException(State.ERR_NOT_FOUND,"更新信息失败,数据不存在");
        }
        CategoryStandardVO categoryStandardVOByName = mapper.getByName(categoryUpdateDTO.getName());
        if (categoryStandardVOByName!=null&&categoryStandardVOByName.getId().equals(id)){
            throw new ServiceException(State.ERR_UPDATE,"更新失败,类别名称:"+categoryUpdateDTO.getName()+"已存在");
        }

        Category category = new Category();
        BeanUtils.copyProperties(categoryUpdateDTO,category);
        category.setId(id);
        LastUpdateTime(categoryUpdateDTO);
        int rows = mapper.updateBasicCategoryInformation(category);
        if (rows != 1){
            throw new ServiceException(State.ERR_BAD_REQUEST,"更新失败,服务器忙,请稍后再次尝试");
        }

    }



    @Override
    public void setCategoryIsEnableById(Long id) {
        CategoryStandardVO categoryStandardVOById = mapper.getById(id);
        if (categoryStandardVOById == null){
            throw new ServiceException(State.ERR_NOT_FOUND,"启用类别失败,数据不存在");
        }
        if (categoryStandardVOById.getIsEnable().equals(1)){
            throw new ServiceException(State.ERR_BAD_REQUEST,"启用类别失败,该类别目前已经被使用");
        }
        LastUpdateTime(categoryStandardVOById);
        int rows = mapper.updateIsEnableById(id, 1);
        if (rows!=1){
            throw new ServiceException(State.ERR_BAD_REQUEST,"启用类别失败,服务器忙,请稍后再次尝试");
        }
    }

    @Override
    public void setCategoryIsDisplayById(Long id) {
        CategoryStandardVO categoryStandardVOById = mapper.getById(id);
        if (categoryStandardVOById == null){
            throw new ServiceException(State.ERR_NOT_FOUND,"显示类别失败,数据不存在");
        }
        if (categoryStandardVOById.getIsEnable().equals(1)){
            throw new ServiceException(State.ERR_BAD_REQUEST,"显示类别失败,该类别目前已经显示在导航栏中");
        }
        LastUpdateTime(categoryStandardVOById);
        int rows = mapper.updateIsDisplayById(id, 1);
        if (rows!=1){
            throw new ServiceException(State.ERR_BAD_REQUEST,"显示类别失败,服务器忙,请稍后再次尝试");
        }
    }

    @Override
    public void setCategoryIsCancelById(Long id) {
        CategoryStandardVO categoryStandardVOById = mapper.getById(id);
        if (categoryStandardVOById == null){
            throw new ServiceException(State.ERR_NOT_FOUND,"禁用类别失败,数据不存在");
        }
        if (categoryStandardVOById.getIsCancel().equals(1)){
            throw new ServiceException(State.ERR_BAD_REQUEST,"禁用类别失败,类别当前已经作废");
        }
        LastUpdateTime(categoryStandardVOById);
        int rows = mapper.updateIsCancelById(id, 1);
        if (rows!=1){
            throw new ServiceException(State.ERR_BAD_REQUEST,"禁用类别失败,服务器忙,请稍后再次尝试");
        }
    }

    /**
     * 查询所有类别列表
     * @return
     */
    @Override
    public List<CategoryStandardVO> getCategoryList() {
        return mapper.selectAllCategories();
    }

    @Override
    public CategoryTreeVO categoryTree() {
        List<CategoryStandardVO> categoryStandardVOs = getCategoryList();
        CategoryTreeVO<FrontCategoryEntity> treeVO=tree(categoryStandardVOs);
        return treeVO;
    }




    @Override
    public CategoryStandardVO selectById(Long id) {
        CategoryStandardVO categoryStandardVO = mapper.getById(id);
        return categoryStandardVO;
    }


    @Override
    public CategoryStandardVO selectByName(String name) {
        CategoryStandardVO categoryStandardVO = mapper.getByName(name);
        return categoryStandardVO;
    }




    // 更新表的最后更改时间
    private void LastUpdateTime(CategoryStandardVO categoryStandardVO) {
        categoryStandardVO.setGmtModified(LocalDateTime.now());
    }
    // 更新表的最后更改时间
    private void LastUpdateTime(CategoryUpdateDTO categoryUpdateDTO) {
        categoryUpdateDTO.setGmtModified(LocalDateTime.now());
    }



    private CategoryTreeVO<FrontCategoryEntity> tree(List<CategoryStandardVO> categoryStandardVOs) {
        Map<Long,List<FrontCategoryEntity>> map=new HashMap<>();
        log.info("当前分类对象总数:{}",categoryStandardVOs.size());
        for(CategoryStandardVO categoryStandardVO : categoryStandardVOs){
            FrontCategoryEntity frontCategoryEntity=new FrontCategoryEntity();
            BeanUtils.copyProperties(categoryStandardVO,frontCategoryEntity);
            Long parentId=frontCategoryEntity.getParentId();
            if(!map.containsKey(parentId)){
                List<FrontCategoryEntity> value=new ArrayList<>();
                value.add(frontCategoryEntity);
                map.put(parentId,value);
            }else{
                map.get(parentId).add(frontCategoryEntity);
            }
        }
        log.info("当前map中包含父级id的个数为:{}",map.size());
        List<FrontCategoryEntity> firstLevels=map.get(0L);
        if(firstLevels==null){
            throw new ServiceException(State.ERR_NOT_FOUND,"当前项目没有根分类");
        }
        for(FrontCategoryEntity oneLevel: firstLevels){
            Long secondLevelParentId=oneLevel.getId();
            List<FrontCategoryEntity> secondLevels=map.get(secondLevelParentId);
            if(secondLevels==null){
                log.warn("当前分类缺少二级分类内容:{}",secondLevelParentId);
                continue;
            }
            // 遍历当前根分类的所有二级分类
            for(FrontCategoryEntity twoLevel : secondLevels){
                Long thirdLevelParentId = twoLevel.getId();
                List<FrontCategoryEntity> thirdLevels=map.get(thirdLevelParentId);
                if(thirdLevels==null){
                    log.warn("当前分类缺少三级分类内容:{}",thirdLevelParentId);
                    continue;
                }
                twoLevel.setChildrens(thirdLevels);
            }
            oneLevel.setChildrens(secondLevels);
        }
        CategoryTreeVO<FrontCategoryEntity> treeVO=new CategoryTreeVO<>();
        treeVO.setCategories(firstLevels);
        return treeVO;

    }


}
